package net.fredstar.polarbear;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

/**
 * TODO Comments.
 * 
 * @author Matthew Blackford [matthew@fredstar.net]
 */
public class SSLContextFactory
{
  private static final SSLContextFactory INSTANCE = new SSLContextFactory();
  
  /**
   * Gets the instance.
   * 
   * @return the instance.
   */
  public static SSLContextFactory getInstance()
  {
    return INSTANCE;
  }
  
  private SSLContextFactory()
  {
    // No implementation required
  }
  
  /**
   * TODO Comments.
   * 
   * @param keyStoreName
   * @param keyStorePassword
   * @param trustStoreName
   * @param trustStorePassword
   * @return
   * @throws IOException
   * @throws GeneralSecurityException
   */
  public SSLContext createSecureContext( final String keyStoreName,
      final String keyStorePassword, final String trustStoreName,
      final String trustStorePassword ) throws IOException,
      GeneralSecurityException
  {
    // Create the key store and trust store
    KeyStore keyStore = KeyStore.getInstance( "JKS" );
    KeyStore trustStore = KeyStore.getInstance( "JKS" );
    
    // Convert the key store password into an array
    char[] keyStorePasswordArray = keyStorePassword.toCharArray();
    
    // Load the key store
    FileInputStream keyInputStream = new FileInputStream( keyStoreName );
    keyStore.load( keyInputStream, keyStorePasswordArray );
    
    // Convert the trust store password into an array
    char[] trustStorePasswordArray = trustStorePassword.toCharArray();
    
    // Load the trust store
    FileInputStream trustInputStream = new FileInputStream( trustStoreName );
    trustStore.load( trustInputStream, trustStorePasswordArray );
    
    // Create the key manager and trust manager factories
    KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );
    TrustManagerFactory tmf = TrustManagerFactory.getInstance( "SunX509" );
    
    // Load the client keystore and password to the key manager factory
    kmf.init( keyStore, keyStorePasswordArray );
    
    // load client truststore into trust manager factory.
    tmf.init( trustStore );
    
    // Create the SSL context load the factories into it
    SSLContext context = SSLContext.getInstance( "TLS" );
    context.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null );
    
    // Return the context
    return context;
  }
}
